package org.merak.core.persistence.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import org.apache.log4j.Logger;
import org.merak.core.model.SettingException;
import org.merak.core.persistence.jdbc.settings.ConnectionDetail;
import org.merak.core.persistence.jdbc.settings.ConnectionSetting;
import org.merak.core.persistence.jdbc.settings.SettingType;

class SQLConnectionFactory {

	//~ Attributes ///////////////////////////////////////////////////////////////
	//****************************************************************************
	private static Logger logger = Logger.getLogger("Database");

    //~ Methods //////////////////////////////////////////////////////////////////
    //****************************************************************************
	public static Connection connectTo(ConnectionSetting settings)
		throws SQLException, NamingException
	{
		// Log we are going to connect...
		logger.info(
			"Connecting to '"+settings.getId()+"' (" + settings.getUrl() + ")"
		);

		// Retrieve the parameters to create the connection
		ConnectionDetail params = settings.getDetail();

		// Try connecting through a DataSource
		if (settings.getType() == SettingType.DATA_SOURCE ) {
			return connectToDataSource(settings.getUrl());
		}

		// Try a direct connection
		try { return connectTo(
			params.getDriver(),
			settings.getUrl(),
			params.getUsername(),
			params.getPassword()
		);}
		catch (ClassNotFoundException e) { throw new SettingException(
			settings.getUrl() + ": " + params.getSystem() +
			" driver (" + e.getMessage() +
			") is not installed. Check for missing *.jar files."
		);}

	}
    //****************************************************************************
	private static Connection connectTo(String driver,String url,String user,String password)
		throws ClassNotFoundException, SQLException
	{
		// Register the database driver and connect
		Class.forName(driver);		
		return DriverManager.getConnection(url,user,password);

	}
	//****************************************************************************
	private static Connection connectToDataSource(String url)
		throws NamingException, SQLException
	{
		// Look-up the DataSource in the context
		Context    ctx = new InitialContext();
		DataSource ds  = (DataSource) ctx.lookup(url);

		// Throw error if DataSource does not exist
		if (ds==null) throw new SettingException (
			"DataSource '"+url+"' is not defined."
		);

		// Connect
		return ds.getConnection();

	}
	//****************************************************************************

}
